<template>
  <div class="live-view">
    <div class="header">
      <h2>实时监控</h2>
      <div class="controls">
        <a-select v-model:value="layoutType" style="width: 120px; margin-right: 16px;" @change="handleLayoutChange">
          <a-select-option value="1x1">1×1</a-select-option>
          <a-select-option value="2x2">2×2</a-select-option>
          <a-select-option value="3x3">3×3</a-select-option>
          <a-select-option value="4x4">4×4</a-select-option>
        </a-select>
        <a-button @click="refreshCameras" :loading="loading">
          <template #icon><ReloadOutlined /></template>
          刷新摄像头
        </a-button>
        <a-switch 
          v-model:checked="autoRefresh" 
          @change="handleAutoRefreshChange"
          style="margin-left: 12px;"
        >
          <template #checkedChildren>自动刷新</template>
          <template #unCheckedChildren>手动刷新</template>
        </a-switch>
        <a-switch 
          v-model:checked="debugMode" 
          style="margin-left: 12px;"
        >
          <template #checkedChildren>调试模式</template>
          <template #unCheckedChildren>普通模式</template>
        </a-switch>
      </div>
    </div>

    <!-- 空状态 -->
    <div v-if="cameras.length === 0 && !loading" class="empty-state">
      <a-empty description="暂无摄像头数据，请检查后端服务是否正常运行">
        <template #image>
          <VideoCameraOutlined style="font-size: 64px; color: #d9d9d9;" />
        </template>
        <a-button type="primary" @click="refreshCameras" :loading="loading">
          <template #icon><ReloadOutlined /></template>
          重新获取摄像头列表
        </a-button>
      </a-empty>
    </div>

    <!-- 视频网格 -->
    <div v-else class="video-grid" :class="`grid-${layoutType}`">
      <div 
        v-for="(camera, index) in currentPageCameras" 
        :key="camera.id"
        class="video-item"
      >
        <div class="video-header">
          <div class="camera-info">
            <span class="camera-name">{{ camera.name }}</span>
            <div class="camera-details">
              <span class="conf-name">{{ camera.confName }}</span>
              <span class="readers-count">{{ camera.readersCount }} 观看者</span>
            </div>
          </div>
          <div class="camera-status">
            <a-tag :color="camera.status === 'online' ? 'green' : 'red'">
              {{ camera.status === 'online' ? '在线' : '离线' }}
            </a-tag>
            <a-tag v-if="camera.sourceType" color="blue" size="small">
              {{ camera.sourceType }}
            </a-tag>
          </div>
        </div>
        <div class="video-container">
          <VideoPlayer 
            v-if="camera.status === 'online'"
            :stream-url="camera.streamUrl"
            :show-debug="debugMode"
          />
          <div v-else class="offline-placeholder">
            <ExclamationCircleOutlined />
            <p>摄像头离线</p>
          </div>
        </div>
      </div>
    </div>

    <div class="pagination" v-if="cameras.length > 0 && totalPages > 1">
      <a-pagination
        v-model:current="currentPage"
        :total="cameras.length"
        :page-size="getPageSize()"
        :show-size-changer="false"
        :show-quick-jumper="true"
        :show-total="(total: number, range: [number, number]) => `第 ${range[0]}-${range[1]} 条，共 ${total} 条`"
        @change="handlePageChange"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, nextTick } from 'vue'
import { message } from 'ant-design-vue'
import { ReloadOutlined, ExclamationCircleOutlined } from '@ant-design/icons-vue'
import { cameraApi, CameraDataConverter, type Camera } from '@/services/api'
import VideoPlayer from '@/components/VideoPlayer.vue'

const layoutType = ref('2x2')
const currentPage = ref(1)
const loading = ref(false)
const cameras = ref<Camera[]>([])
const videoRefs = ref<HTMLVideoElement[]>([])
const autoRefresh = ref(false)
const refreshInterval = ref<number | null>(null)
const debugMode = ref(false)


const getPageSize = () => {
  const layoutMap: Record<string, number> = {
    '1x1': 1,
    '2x2': 4,
    '3x3': 9,
    '4x4': 16
  }
  return layoutMap[layoutType.value] || 4
}

const totalPages = computed(() => {
  return Math.ceil(cameras.value.length / getPageSize())
})

const currentPageCameras = computed(() => {
  const pageSize = getPageSize()
  const start = (currentPage.value - 1) * pageSize
  const end = start + pageSize
  return cameras.value.slice(start, end)
})

const setVideoRef = (el: any, index: number) => {
  if (el && el instanceof HTMLVideoElement) {
    videoRefs.value[index] = el
  }
}

const handleLayoutChange = () => {
  currentPage.value = 1
  // 重新加载视频流
  nextTick(() => {
    loadVideoStreams()
  })
}

const handlePageChange = (page: number) => {
  currentPage.value = page
  nextTick(() => {
    loadVideoStreams()
  })
}

const loadVideoStreams = () => {
  videoRefs.value.forEach((video, index) => {
    if (video && currentPageCameras.value[index]?.status === 'online') {
      video.load()
    }
  })
}

const handleVideoError = (cameraId: string, event: Event) => {
  const video = event.target as HTMLVideoElement
  const error = video.error
  let errorMessage = `摄像头 ${cameraId} 视频加载失败`
  
  if (error) {
    switch (error.code) {
      case MediaError.MEDIA_ERR_ABORTED:
        errorMessage += ': 视频加载被中止'
        break
      case MediaError.MEDIA_ERR_NETWORK:
        errorMessage += ': 网络错误'
        break
      case MediaError.MEDIA_ERR_DECODE:
        errorMessage += ': 视频解码错误'
        break
      case MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED:
        errorMessage += ': 视频格式不支持'
        break
      default:
        errorMessage += `: 未知错误 (${error.code})`
    }
  }
  
  console.error(`摄像头 ${cameraId} 视频错误:`, {
    error: error,
    src: video.src,
    networkState: video.networkState,
    readyState: video.readyState
  })
  
  message.error(errorMessage)
}

const handleVideoLoadStart = (cameraId: string) => {
  console.log(`摄像头 ${cameraId} 开始加载视频`)
}

const handleVideoCanPlay = (cameraId: string) => {
  console.log(`摄像头 ${cameraId} 视频可以播放`)
}

const handleVideoLoadedData = (cameraId: string) => {
  console.log(`摄像头 ${cameraId} 视频数据加载完成`)
}



const refreshCameras = async (showMessage: boolean = true) => {
  loading.value = true
  try {
    const pathList = await cameraApi.getPathsList(0, 1000) // 获取所有摄像头
    cameras.value = CameraDataConverter.pathsToCameras(pathList.items)
    if (showMessage && !autoRefresh.value) {
      message.success(`成功获取 ${cameras.value.length} 个摄像头`)
    }
  } catch (error) {
    console.error('获取摄像头列表失败:', error)
    if (showMessage && !autoRefresh.value) {
      message.error(`获取摄像头列表失败: ${error instanceof Error ? error.message : '未知错误'}`)
    }
    // 如果API调用失败，使用空数组
    cameras.value = []
  } finally {
    loading.value = false
  }
}

const handleAutoRefreshChange = (checked: boolean) => {
  if (checked) {
    // 开启自动刷新，每30秒刷新一次
    refreshInterval.value = setInterval(() => {
      refreshCameras(false) // 自动刷新时不显示消息
    }, 30000)
    message.info('已开启自动刷新，每30秒更新一次')
  } else {
    // 关闭自动刷新
    if (refreshInterval.value) {
      clearInterval(refreshInterval.value)
      refreshInterval.value = null
    }
    message.info('已关闭自动刷新')
  }
}

onMounted(() => {
  // 页面加载后自动获取摄像头列表，首次加载不显示消息
  refreshCameras(false)
})

onUnmounted(() => {
  // 清理视频流
  videoRefs.value.forEach(video => {
    if (video) {
      video.pause()
      video.src = ''
    }
  })
  
  // 清理自动刷新定时器
  if (refreshInterval.value) {
    clearInterval(refreshInterval.value)
  }
})
</script>

<style scoped>
.live-view {
  min-height: calc(100vh - 0px);
  padding: 24px;
  background: #fff;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
  flex-wrap: wrap;
  gap: 16px;
}

.header h2 {
  margin: 0;
  color: #1890ff;
}

.controls {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

.video-grid {
  display: grid;
  gap: 16px;
  margin-bottom: 24px;
  width: 100%;
}

.grid-1x1 {
  grid-template-columns: 1fr;
  max-width: 100%;
}

.grid-1x1 .video-container {
  aspect-ratio: 16/9;
  min-height: 60vh; /* 1×1布局时最小高度为视口高度的60% */
}

.grid-2x2 {
  grid-template-columns: repeat(2, 1fr);
}

.grid-2x2 .video-container {
  aspect-ratio: 16/9;
  min-height: 30vh; /* 2×2布局时最小高度为视口高度的30% */
}

.grid-3x3 {
  grid-template-columns: repeat(3, 1fr);
}

.grid-3x3 .video-container {
  aspect-ratio: 16/9;
  min-height: 20vh; /* 3×3布局时最小高度为视口高度的20% */
}

.grid-4x4 {
  grid-template-columns: repeat(4, 1fr);
}

.grid-4x4 .video-container {
  aspect-ratio: 16/9;
  min-height: 15vh; /* 4×4布局时最小高度为视口高度的15% */
}

.video-item {
  border: 1px solid #d9d9d9;
  border-radius: 8px;
  overflow: hidden;
  background: #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.video-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  padding: 8px 12px;
  background: #f5f5f5;
  border-bottom: 1px solid #d9d9d9;
}

.camera-info {
  flex: 1;
}

.camera-name {
  font-weight: 500;
  color: #262626;
  display: block;
  margin-bottom: 4px;
}

.camera-details {
  font-size: 12px;
  color: #8c8c8c;
}

.conf-name {
  margin-right: 8px;
}

.readers-count {
  color: #1890ff;
}

.camera-status {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
}

.video-container {
  position: relative;
  width: 100%;
  background: #000;
  border-radius: 4px;
  overflow: hidden;
  aspect-ratio: 16/9; /* 保持16:9的宽高比 */
}

.video-container video {
  width: 100%;
  height: 100%;
  object-fit: contain; /* 改为contain以保持完整画面 */
}

.offline-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #999;
}

.offline-placeholder .anticon {
  font-size: 32px;
  margin-bottom: 8px;
}

.empty-state {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 400px;
  background: #fafafa;
  border-radius: 8px;
  border: 1px dashed #d9d9d9;
}

.pagination {
  display: flex;
  justify-content: center;
  margin-top: 24px;
}

@media (max-width: 1200px) {
  .grid-4x4 {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (max-width: 900px) {
  .grid-3x3,
  .grid-4x4 {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 1200px) {
  .grid-4x4 {
    grid-template-columns: repeat(3, 1fr);
  }
  
  .grid-4x4 .video-container {
    min-height: 18vh;
  }
  
  .live-view {
    padding: 16px;
  }
}

@media (max-width: 900px) {
  .grid-3x3,
  .grid-4x4 {
    grid-template-columns: repeat(2, 1fr);
  }
  
  .grid-3x3 .video-container,
  .grid-4x4 .video-container {
    min-height: 25vh;
  }
  
  .grid-1x1 .video-container {
    min-height: 50vh;
  }
  
  .grid-2x2 .video-container {
    min-height: 25vh;
  }
}

@media (max-width: 600px) {
  .grid-2x2,
  .grid-3x3,
  .grid-4x4 {
    grid-template-columns: 1fr;
  }
  
  .grid-2x2 .video-container,
  .grid-3x3 .video-container,
  .grid-4x4 .video-container {
    min-height: 30vh;
  }
  
  .grid-1x1 .video-container {
    min-height: 40vh;
  }
  
  .header {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
  }
  
  .controls {
    width: 100%;
    justify-content: flex-start;
  }
  
  .live-view {
    padding: 12px;
  }
}
</style>
